package com.rules.admin.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rules.admin.utils.ResultUtils;
import com.gillion.grule.client.core.DataType;
import com.rules.admin.entity.UnitCaseParam;
import com.rules.admin.service.UnitCaseParamService;
import com.rules.admin.utils.TypeTransform;
import org.apache.commons.collections.map.HashedMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping({"/unitcases"})
public class UnitCaseParamController {
   private static final Logger LOGGER = LoggerFactory.getLogger(UnitCaseParamController.class);
   @Autowired
   private UnitCaseParamService unitCaseParamService;

   @RequestMapping(
      value = {"/params"},
      method = {RequestMethod.POST}
   )
   @ResponseBody
   public Map<String, Object> createParam(@RequestBody UnitCaseParam unitCaseParam) {
      this.unitCaseParamService.save(unitCaseParam);
      return ResultUtils.getSuccessResultData(unitCaseParam);
   }

   @RequestMapping(
      value = {"/params/{id}"},
      method = {RequestMethod.DELETE}
   )
   @ResponseBody
   public Map<String, Object> deleteParam(@PathVariable("id") Long id) {
      boolean result = this.unitCaseParamService.removeById(id);
      return result ? ResultUtils.getSuccessResultData() : ResultUtils.getFaildResultData(new String[]{"删除失败"});
   }

   @RequestMapping(
      value = {"/params/{id}"},
      method = {RequestMethod.PUT}
   )
   @ResponseBody
   public Map<String, Object> updateParam(@RequestBody UnitCaseParam expectParam) {
      this.unitCaseParamService.updateById(expectParam);
      return ResultUtils.getSuccessResultData(expectParam);
   }

   @RequestMapping(
      value = {"/params/{id}"},
      method = {RequestMethod.GET}
   )
   @ResponseBody
   public List<UnitCaseParam> findParam(@PathVariable("id") Long unitCaseId) {
      return this.unitCaseParamService.getAllParamByCaseId(unitCaseId);
   }

   @RequestMapping(
      value = {"/newParams/{id}"},
      method = {RequestMethod.GET}
   )
   @ResponseBody
   public Map<String, Object> findParam2(@PathVariable("id") Long unitCaseId) {
      return ResultUtils.getSuccessResultData(this.unitCaseParamService.getAllParamByCaseId(unitCaseId));
   }

   @RequestMapping(
      value = {"/params/child/{id}"},
      method = {RequestMethod.GET}
   )
   @ResponseBody
   public Map<String, Object> findChild(@PathVariable("id") Long id) {
      return ResultUtils.getSuccessResultData(this.unitCaseParamService.getAllParamByParentId(id));
   }

   @RequestMapping(
      value = {"/importParams"},
      method = {RequestMethod.POST}
   )
   @ResponseBody
   public Map<String, Object> importParams(HttpServletRequest request, HttpServletResponse response, Long unitCaseId) {
      MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest)request;
      MultipartFile multipartFile = multipartRequest.getFile("file");

      try {
         String jsonstr = TypeTransform.inputStream2String(multipartFile.getInputStream());
         JSONArray list = JSON.parseArray(jsonstr);
         Iterator var8 = list.iterator();

         while(var8.hasNext()) {
            Object obj = var8.next();
            JSONObject jsonObj = (JSONObject)obj;
            this.map2Data(jsonObj, unitCaseId);
         }
      } catch (Exception var11) {
         LOGGER.error("导入失败！", var11);
         return ResultUtils.getFaildResultData(new String[]{"导入失败，请检查数据格式！"});
      }

      return ResultUtils.getSuccessResultData();
   }

   public void map2Data(JSONObject obj, Long unitCaseId) {
      UnitCaseParam param = new UnitCaseParam();
      param.setParamName(obj.get("paramName").toString());
      param.setParam(obj.get("param").toString());
      param.setUnitCaseId(unitCaseId);
      param.setDataType(DataType.valueOf(obj.get("dataType").toString()));
      if (obj.get("parentId") != null && !"".equals(obj.get("parentId"))) {
         param.setParentId(Long.valueOf(obj.get("parentId").toString()));
      }

      this.unitCaseParamService.save(param);
      if ("Object".equals(obj.get("dataType").toString()) && obj.get("children") != null) {
         List list = (List)obj.get("children");
         Iterator var5 = list.iterator();

         while(var5.hasNext()) {
            Object o = var5.next();
            JSONObject jsonObj = (JSONObject)o;
            jsonObj.put("parentId", param.getId());
            this.map2Data(jsonObj, unitCaseId);
         }
      }

   }

   @RequestMapping(
      value = {"/importParams2"},
      method = {RequestMethod.POST}
   )
   @ResponseBody
   public Map<String, Object> importParams2(HttpServletRequest request, HttpServletResponse response, Long unitCaseId) {
      MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest)request;
      MultipartFile multipartFile = multipartRequest.getFile("file");

      try {
         String jsonstr = TypeTransform.inputStream2String(multipartFile.getInputStream());
         JSONArray list = JSON.parseArray(jsonstr);

         for(int i = 0; i < list.size(); ++i) {
            this.jsonObjToDate("params" + i, list.get(i), (Long)null, unitCaseId);
         }
      } catch (Exception var9) {
         LOGGER.error("导入失败！", var9);
         return ResultUtils.getFaildResultData(new String[]{"导入失败，请检查数据格式！"});
      }

      return ResultUtils.getSuccessResultData();
   }

   public void jsonObjToDate(String key, Object value, Long parentId, Long unitcase) {
      UnitCaseParam param = new UnitCaseParam();
      param.setParentId(parentId);
      param.setParamName(key);
      param.setUnitCaseId(unitcase);
      if (value instanceof BigDecimal) {
         param.setParam(value.toString());
         param.setDataType(DataType.Double);
         this.unitCaseParamService.save(param);
      } else if (value instanceof Integer) {
         param.setParam(value.toString());
         param.setDataType(DataType.Integer);
         this.unitCaseParamService.save(param);
      } else if (value instanceof String) {
         if ("".equals(value)) {
            value = "''";
         }

         param.setParam(value.toString());
         param.setDataType(DataType.String);
         this.unitCaseParamService.save(param);
      } else if (value instanceof Long) {
         param.setParam(value.toString());
         param.setDataType(DataType.Long);
         this.unitCaseParamService.save(param);
      } else if (value instanceof Boolean) {
         param.setParam(value.toString());
         param.setDataType(DataType.Boolean);
         this.unitCaseParamService.save(param);
      } else if (value instanceof Map) {
         param.setParam("-");
         param.setDataType(DataType.Object);
         this.unitCaseParamService.save(param);
         Iterator var6 = ((Map)value).keySet().iterator();

         while(var6.hasNext()) {
            Object mapKey = var6.next();
            this.jsonObjToDate(mapKey.toString(), ((Map)value).get(mapKey), param.getId(), unitcase);
         }
      } else if (value instanceof List) {
         param.setParam(value.toString());
         param.setDataType(DataType.List);
         this.unitCaseParamService.save(param);
      } else if (value == null) {
         param.setParam("null");
         param.setDataType(DataType.String);
         this.unitCaseParamService.save(param);
      }

   }

   @RequestMapping({"/paramsToJson"})
   @ResponseBody
   public void paramsToFile(HttpServletRequest request, HttpServletResponse response, Long unitCaseId) throws Exception {
      List<UnitCaseParam> params = this.unitCaseParamService.getAllParamByCaseId(unitCaseId);
      List list = new ArrayList();
      Iterator var6 = params.iterator();

      while(var6.hasNext()) {
         UnitCaseParam unitCaseParam = (UnitCaseParam)var6.next();
         if (unitCaseParam.getDataType() == DataType.Object) {
            List<UnitCaseParam> childrenParams = this.unitCaseParamService.getAllParamByParentId(unitCaseParam.getId());
            Map map = new HashedMap();
            list.add(map);
            this.childToJson(childrenParams, map);
         } else if (unitCaseParam.getDataType() == DataType.List) {
            list.add(JSONArray.parseArray(unitCaseParam.getParam()));
         } else if (unitCaseParam.getDataType() == DataType.String) {
            list.add(unitCaseParam.getParam());
         } else if (unitCaseParam.getDataType() == DataType.Long) {
            list.add(Long.valueOf(unitCaseParam.getParam()));
         } else if (unitCaseParam.getDataType() == DataType.Integer) {
            list.add(Integer.valueOf(unitCaseParam.getParam()));
         } else if (unitCaseParam.getDataType() == DataType.Double) {
            list.add(new BigDecimal(unitCaseParam.getParam()));
         } else if (unitCaseParam.getDataType() == DataType.Boolean) {
            list.add(Boolean.valueOf(unitCaseParam.getParam()));
         }
      }

      String json = JSONArray.toJSONString(list);
      System.out.println(json);
      response.reset();
      response.setHeader("Content-Disposition", "attachment;filename=\"" + URLEncoder.encode("参数", "UTF-8") + "\"");
      response.addHeader("Content-Length", "" + json.getBytes("utf-8").length);
      response.setContentType("application/octet-stream;charset=utf-8");
      OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
      outputStream.write(json.getBytes("utf-8"));
      outputStream.flush();
      response.flushBuffer();
      outputStream.close();
   }

   private void wrapResponse(HttpServletResponse response, Map<String, Object> result, String headScript) {
      ObjectMapper objectMapper = new ObjectMapper();

      try {
         response.setContentType("text/html; charset=utf-8");
         PrintWriter printWriter = response.getWriter();
         String resultString = objectMapper.writeValueAsString(result);
         String html = "<html>" + headScript + "<body>" + resultString + "</body></html>";
         printWriter.write(html);
         printWriter.flush();
         printWriter.close();
      } catch (Exception var8) {
         var8.printStackTrace();
      }

   }

   public void childToJson(List<UnitCaseParam> params, Map map) {
      Iterator var3 = params.iterator();

      while(var3.hasNext()) {
         UnitCaseParam unitCaseParam = (UnitCaseParam)var3.next();
         if (unitCaseParam.getDataType() == DataType.Object) {
            List<UnitCaseParam> childrenParams = this.unitCaseParamService.getAllParamByParentId(unitCaseParam.getId());
            Map childMap = new HashedMap();
            map.put(unitCaseParam.getParamName(), childMap);
            this.childToJson(childrenParams, childMap);
         } else if (unitCaseParam.getDataType() == DataType.List) {
            map.put(unitCaseParam.getParamName(), JSONArray.parseArray(unitCaseParam.getParam()));
         } else if (unitCaseParam.getDataType() == DataType.String) {
            map.put(unitCaseParam.getParamName(), unitCaseParam.getParam());
         } else if (unitCaseParam.getDataType() == DataType.Long) {
            map.put(unitCaseParam.getParamName(), Long.valueOf(unitCaseParam.getParam()));
         } else if (unitCaseParam.getDataType() == DataType.Integer) {
            map.put(unitCaseParam.getParamName(), Integer.valueOf(unitCaseParam.getParam()));
         } else if (unitCaseParam.getDataType() == DataType.Double) {
            map.put(unitCaseParam.getParamName(), new BigDecimal(unitCaseParam.getParam()));
         } else if (unitCaseParam.getDataType() == DataType.Boolean) {
            map.put(unitCaseParam.getParamName(), Boolean.valueOf(unitCaseParam.getParam()));
         }
      }

   }
}
